package org.orz.cloud.auth;

import cn.hutool.core.util.StrUtil;
import org.orz.cloud.auth.utils.NetUtils;
import org.orz.cloud.common.utils.ThreadLocalUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.UUID;

import static org.orz.cloud.auth.AuthConstants.TRACE_ID;
import static org.orz.cloud.auth.AuthConstants.USER_TOKEN_KEY;

/**
 * 对请求中的token做处理的拦截器
 */
public class RequestPreInterceptor implements HandlerInterceptor {
    private static Logger log = LoggerFactory.getLogger("framework-request");

    public RequestPreInterceptor() {
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }

        log.debug("Register response and request object.");
        if (!"/".equals(request.getRequestURI()) && log.isTraceEnabled()) {
            log.trace("Request: " + request.getRequestURI() + " from: " + NetUtils.getRemoteIp(request));
        }
        log.debug("Getting token from " + request.getRequestURL() + " with method: " + request.getMethod());

        // 从请求头中，取出token
        String token = this.getTokenString(request);
        if (StrUtil.isNotBlank(token)) {
            // 将token放入threadLocal中
            ThreadLocalUtils.setValue(USER_TOKEN_KEY, token);
        }
        //设置当前请求的traceId
        String traceId = UUID.randomUUID().toString();
        response.setHeader("trace", traceId);
        ThreadLocalUtils.setValue(TRACE_ID, traceId);
        return true;
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("clean user in memory");
        }

        ThreadLocalUtils.clear();
    }

    private String getTokenString(HttpServletRequest httpServletRequest) {
        String token = httpServletRequest.getHeader(AuthConstants.HEADER_AUTHORIZATION);
        if (StrUtil.isBlank(token)) {
            token = httpServletRequest.getHeader(AuthConstants.HEADER_AUTHORIZATION);
        }
        return token;
    }
}
